package com.andaily.infrastructure.mail.mailgun;

import com.andaily.infrastructure.support.LogHelper;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import org.springframework.core.io.AbstractResource;

import javax.ws.rs.core.MediaType;
import java.util.Map;

/**
 * @author Shengzhao Li
 */
public class MailgunSendMailHandler extends Thread {

    private static LogHelper log = LogHelper.create(MailgunSendMailHandler.class);

    private static String apiKey;
    private static String messagesUri;

    private static String defaultAddress;
    private static boolean developEnvironment;
    private static String developEmailAddress;

    //mail fields
    private String from;
    private String to[];
    private String subject;
    private String content;
    private Map<String, AbstractResource> attachments;
    private Map<String, AbstractResource> inlineResources;
    //The operation is success or not
    private boolean handleResult;

    public MailgunSendMailHandler() {
    }

    public MailgunSendMailHandler(String subject, String content, String... to) {
        this.to = to;
        this.subject = subject;
        this.content = content;
        //default value
        this.from = defaultAddress;
    }

    public MailgunSendMailHandler from(String from) {
        this.from = from;
        return this;
    }


    public MailgunSendMailHandler attachments(Map<String, AbstractResource> attachments) {
        this.attachments = attachments;
        return this;
    }

    public MailgunSendMailHandler inlineResources(Map<String, AbstractResource> inlineResources) {
        this.inlineResources = inlineResources;
        return this;
    }


    public boolean handle(boolean sendMailUseThread) {
        if (sendMailUseThread) {
            log.debug("Send mail use new Thread");
            this.start();
            this.handleResult = true;
        } else {
            this.run();
        }
        return handleResult;
    }

    private void setTo(MultivaluedMapImpl formData) {
        //Check develop environment or not.
        if (developEnvironment) {
            log.info("NOTE: Current environment is Test, The email will be send to developer [" + developEmailAddress + "]");
            formData.add("to", developEmailAddress);
        } else {
            for (String toAddress : to) {
                formData.add("to", toAddress);
            }
        }
    }

    public void run() {
        try {
            Client client = Client.create();
            client.addFilter(new HTTPBasicAuthFilter("api", apiKey));
            WebResource webResource = client.resource(messagesUri);

            MultivaluedMapImpl formData = new MultivaluedMapImpl();
            formData.add("from", from);
            setTo(formData);
            formData.add("subject", subject);
            formData.add("html", content);
            //attachments

            //inline resources


            WebResource.Builder builder = webResource.type(MediaType.APPLICATION_FORM_URLENCODED);
            ClientResponse response = builder.
                    post(ClientResponse.class, formData);
            int status = response.getStatus();
            log.debug("Send mail status: " + status);
            handleResult = (status == 200);

        } catch (Exception e) {
            handleResult = false;
            log.error("Send Email error", e);
        }
    }


    public void setDefaultAddress(String defaultAddress) {
        MailgunSendMailHandler.defaultAddress = defaultAddress;
    }


    public void setDevelopEnvironment(boolean developEnvironment) {
        MailgunSendMailHandler.developEnvironment = developEnvironment;
    }

    public void setDevelopEmailAddress(String developEmailAddress) {
        MailgunSendMailHandler.developEmailAddress = developEmailAddress;
    }

    public void setApiKey(String apiKey) {
        MailgunSendMailHandler.apiKey = apiKey;
    }

    public void setMessagesUri(String messagesUri) {
        MailgunSendMailHandler.messagesUri = messagesUri;
    }
}
